package com.atguigu.gulimall.search.thread;


import java.util.concurrent.*;

/**
 * @Author:Panghl
 * @Description: CompletableFuture异步编排
 * @Date: Created in 20:53 2022/7/4
 * @Modified By:
 */
public class ThreadTest {

    private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 20,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());

    public static void CompletableFuture(String[] args) throws ExecutionException, InterruptedException {
//        CompletableFuture.runAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getName());
//            int i = 10 / 2;
//            System.out.println("运行结果：" + i);
//        }, executor);

        /**
         * 方法执行完成后的感知
         */
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getName());
//            int i = 10 / 2;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executor)// 计算完成时回调方法  whenCompleteAsync：是执行把whenCompleteAsync这个任务继续提交给线程池来进行执行
//                .whenComplete((ret, ex) -> {
//                    // 虽然能得到异常信息，但是没法修改返回数据。
//                    System.out.println("异步任务成功完成了...结果是：" + ret + "，异常是:" + ex);
//                }) //异常
//                .exceptionally((throwable) -> {
//                    // 感知异常，同时返回默认值
//                    return 10;
//                });

        /**
         * 方法执行完成后的处理
         */
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getName());
//            int i = 10 / 2;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executor).handle((ret, thr) -> {
//            if (ret != null) {
//                return ret * 2;
//            }
//            if (thr != null) {
//                return 0;
//            }
//            return 0;
//        });

        /**
         * 线程串行化
         * 1）thenRun: 不能获取上一步的执行结果
         * .thenRunAsync(()->{
         *             System.out.println("任务2启动了....");
         *         },executor)
         *
         * 2）能接收上一步结果，但是无返回值
         * .thenAcceptAsync((res)->{
         *             System.out.println("任务2启动了....res:"+res);
         *         },executor)
         * 3) 既能接收上一步的结果，又有返回值
         *.thenApplyAsync((res) -> {
         *             System.out.println("任务2启动了....res:" + res);
         *             return "Hello: " + res;
         *         }, executor)
         */

/*        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程：" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
            return i;
        }, executor).thenApplyAsync((res) -> {
            System.out.println("任务2启动了....res:" + res);
            return "Hello: " + res;
        }, executor);*/

        /**
         * 两个都完成
         */

//        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务1线程：" + Thread.currentThread().getName());
//            int i = 10 / 2;
//            System.out.println("任务1运行结果：" + i);
//            return i;
//        }, executor);
//        CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
//
//            System.out.println("任务2当前线程：" + Thread.currentThread().getName());
//            int i = 10 / 2;
//            try {
//                TimeUnit.SECONDS.sleep(1L);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println("任务2运行结果：" + i);
//
//            return i;
//        }, executor);

//        future01.runAfterBothAsync(future02,()->{
//            System.out.println("任务3开始...");
//        },executor);
        // void accept(T,U)
//        future01.thenAcceptBothAsync(future02, (f1, f2) -> {
//            System.out.println("任务3执行。。。之前的结果：" + f1 + "---" + f2);
//        }, executor);
//        CompletableFuture<Integer> futureRet = future01.thenCombineAsync(future02, (f1, f2) -> {
//            System.out.println("任务3执行。。。之前的结果：" + f1 + "---" + f2);
//            return f1 + f2;
//        }, executor);

        /**
         * 两个任务，只要有一个完成，就执行任务3
         * runAfterEitherAsync: 不感知结果，自己业务返回值
         * applyToEitherAsync: 感知结果，自己返回结果
         * acceptEitherAsync：感知结果，自己不返回结果
         */
//        future01.runAfterEitherAsync(future02,()->{
//            System.out.println("任务3执行");
//        },executor);

//        future01.applyToEitherAsync(future02, (ret) -> {
//            System.out.println("任务3执行,上一个结果："+ret);
//            return ret*2;
//        }, executor);

//        future01.acceptEitherAsync(future02, (ret) -> {
//            System.out.println("任务3执行,上一个结果："+ret);
//        }, executor);


        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品图片信息");
            return "hello.jpg";
        }, executor);
        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的属性");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "黑色+256G";
        }, executor);
        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品介绍");
            return "华为";
        }, executor);
//        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
        CompletableFuture<Object> anyOf = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
        anyOf.get(); //等待所有结果完成

//        System.out.println("main....end...." + futureImg.get() + "---" + futureAttr.get() + "---" + futureDesc.get());
        System.out.println("main....end...." + anyOf.get());
    }


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test();
    }
    public static void test() throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();
        /*FutureTask futureTask1 = new FutureTask<String>(() -> {
            TimeUnit.SECONDS.sleep(1);
            return "abc";
        });
        FutureTask futureTask3 = new FutureTask<String>(() -> {
            TimeUnit.SECONDS.sleep(3);
            return "abcdada";
        });
        FutureTask futureTask2 = new FutureTask<String>(() -> {
            TimeUnit.SECONDS.sleep(2);
            return "abcda";
        });*/
        CompletableFuture<String> futureTask1 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "abc";
        },executor);
        CompletableFuture<String> futureTask2 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "abc";
        },executor);
        CompletableFuture<String> futureTask3 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "abc";
        },executor);
        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureTask1, futureTask2, futureTask3);
//        executor.execute(futureTask1);
//        executor.execute(futureTask3);
//        executor.execute(futureTask2);
//        futureTask3.get();
//        futureTask1.get();
//        futureTask2.get();
        allOf.get();
        System.out.println("执行时间:" + (System.currentTimeMillis() - start));
    }

}
